package kerjodando.casper.tools;

import kerjodando.casper.util.ConstantUtil;
import kerjodando.casper.util.StringUtil;
import kerjodando.casper.util.HttpUtil;
import kerjodando.vincent.Utils;

import ants.p2p.filesharing.WarriorAnt;
import ants.p2p.gui.DoubleBuffer;
import ants.p2p.gui.FrameAnt;
import ants.p2p.gui.GuiAnt;
import ants.p2p.gui.LabelIcon;
import ants.p2p.gui.QueryAntPanel;
import ants.p2p.gui.ShareAntPanel;
import ants.p2p.query.QueryHashItem;
import ants.p2p.utils.indexer.BackgroundEngine;
import ants.p2p.utils.indexer.FileInfos;
import ants.p2p.utils.indexer.FileSource;

import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

import java.awt.Component;
import java.io.File;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.Hashtable; /*
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors;
 *///import java.util.concurrent.Executors;
import javax.swing.table.TableModel;

import org.apache.log4j.Logger;

public class WebServer {
	private static HttpServer hs;
	private static Object lock = new Object();

	public static void start() {
		synchronized (lock) {
			if (hs != null)
				return;
			try {
				HttpServer hs = HttpServer.create(new InetSocketAddress(
						"127.0.0.1", ConstantUtil.WEBGUI_SERVER_PORT), 0);
				hs.createContext("/webgui/", new WebGuiHandler());
				// hs.setExecutor(Executors.newFixedThreadPool(5));
				hs.setExecutor(null);
				hs.start();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void stop() {
		synchronized (lock) {
			if (hs != null)
				hs.stop(1);
			hs = null;
		}
	}

	private static QueryAntPanel qap = null;

	private static final Logger logger = Logger.getLogger(WebServer.class);

	public static String search(String content, String query, String commit) {
		if (!FrameAnt.getInstance("").getGuiAnt().getConnectionAntPanel()
				.getContainer().queryPanels.isEmpty()) {
			if (WebServer.qap == null) {
				logger.info("qap is null now!");
				GuiAnt container = FrameAnt.getInstance("").getGuiAnt()
						.getConnectionAntPanel().getContainer();
				WebServer.qap = new QueryAntPanel(container);
				container.queryPanels.add(qap);
				container.jTabbedPane1.add(qap, new LabelIcon(
						ji.JI.i("Search"), DoubleBuffer.getInstance()
								.getButton(12), qap));
				container.cap.warriorAnt.getPropertyChangeSupport()
						.addPropertyChangeListener(qap);
			}
			// set the content checkbox
			WebServer.qap.jCheckBox1.setSelected(content.equals("1"));

			WebServer.qap.jTextField1.setText(query);

			if (commit.equals("commit_string")) {
				WebServer.qap.jButton1_actionPerformed(null);
			}

			if (commit.equals("commit_hash")) {
				WebServer.qap.jButton3_actionPerformed(null);
			}
			return "";
		}
		return "setresults(\"kerjodando now is not connected,waiting.....\")";
	}

	public static String refresh() {
		if (WebServer.qap == null)
			return "";
		/*
		 * for (int i = 0; i < m.getColumnCount(); i++) { bf.append("<td>" +
		 * m.getColumnName(i) + "</td>"); }
		 */
		StringBuffer bf = new StringBuffer();
		bf.append("var aRes=[");
		GuiAnt container = FrameAnt.getInstance("").getGuiAnt()
				.getConnectionAntPanel().getContainer();
		TableModel model = WebServer.qap.resultsTable.getModel();
		boolean bIsNotFirst=false;
		for (int row = 0; row < model.getRowCount(); row++) {
			String hashKey = (String) model.getValueAt(row, 6);
			long lSize= WebServer.qap.resultsTable.getFileSizeByHash(hashKey);
			if(lSize<=0)continue;
			if (bIsNotFirst)
			{
				bf.append(',');
			}
			else
				bIsNotFirst=true;
			bf.append('[');
			char cType = '3';
			String sDownStatus = container.dap == null ? "" : container.dap
					.getFileStatus(hashKey, false);
			if (BackgroundEngine.getInstance().getLocalFile(hashKey,
					QueryHashItem.ANTS_HASH) != null
					|| sDownStatus.equals("ok")) {
				cType = '0';// already download
			} else if (BackgroundEngine.getInstance().getPartialFile(hashKey,
					QueryHashItem.ANTS_HASH) != null
					|| (!sDownStatus.equals(""))) {
				cType = '1';// downloading or interrupted
			} else if (((FileSource) model.getValueAt(row, 1))
					.getSourceNumber() == 0) {
				cType = '2';// can't donwload
			}
			bf.append(cType);
			for (int col = 0; col < model.getColumnCount(); col++) {
				bf.append(',');
				bf.append('"');
				bf.append(model.getValueAt(row, col).toString().replace("\"",
						"\\\""));
				bf.append('"');
			}
			bf.append(',');
			bf.append(Long.toString(lSize));
			// can be downloaded
			bf.append(']');
		}
		bf.append("];\r\n");
		bf.append("var dRes=[");
		if (container.dap != null) {
			bf.append(container.dap.getJavaScriptString());
		}
		bf.append("];\r\n");
		return bf.toString() + "dispres(aRes,dRes);";
	}

	public static void sendString(HttpExchange exchange, String sContent,
			int Code) throws IOException {
		exchange.getResponseHeaders().set("Content-Type",
				"text/plain;charset=utf-8");
		exchange.sendResponseHeaders(Code, 0);
		OutputStream os = exchange.getResponseBody();
		PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(os,
				"UTF-8"));
		printWriter.write(sContent);
		printWriter.flush();
		os.close();
	}

	public static String down(String sHashKey) {
		String sResult = WebServer.qap.resultsTable
				.this_mousePressed_by_webgui(sHashKey) ? "dok" : "dno";
		return "showMsg('" + sResult + "');";
	}

	public static String chat(final String sPeerId) {
		Thread t = new Thread(new Runnable() {
			public void run() {
				FrameAnt.getInstance("").getGuiAnt().cap.showPCF(sPeerId);
			}
		});

		t.start();
		return "";
	}
	
	public static String adddir() {
		Thread t = new Thread(new Runnable() {
			public void run() {
				GuiAnt ga = FrameAnt.getInstance("").getGuiAnt();
				Component parent = null;
				if (ga.isVisible()) {
					ga.requestFocus();
					parent = ga;

				}
				ShareAntPanel.addDirectory(parent);
			}
		});

		t.start();
		return "";
	}

	public static void sendFile(HttpExchange exchange, String sHashKey)
			throws IOException {
		try {
			FileInfos fi = BackgroundEngine.getInstance().getLocalFile(
					sHashKey, QueryHashItem.ANTS_HASH);
			String sLocalFileName = fi != null ? fi.getName() : FrameAnt
					.getInstance("").getGuiAnt().getConnectionAntPanel()
					.getContainer().dap.getFileStatus(sHashKey, true);
			if (!StringUtil.isEmptyOrNull(sLocalFileName)) {
				File complete = new File(sLocalFileName);
				FileInputStream fis = new FileInputStream(complete);
				String sFileName = complete.getName();
				Headers headers = exchange.getResponseHeaders();
				headers.set("Content-Type", HttpUtil.getContentType(sFileName));
				headers.set("Content-Disposition", "attachment; filename="
						+ sFileName);
				exchange.sendResponseHeaders(200, complete.length());
				OutputStream os = exchange.getResponseBody();
				byte[] buffer = new byte[4096];
				int bytes = 0;

				// Copy requested file into the socket's output stream.
				while ((bytes = fis.read(buffer)) != -1) {
					os.write(buffer, 0, bytes);
				}
				os.close();
				return;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		sendString(exchange, "File not found!", 404);
	}
}

class WebGuiHandler implements HttpHandler {

	public void handle(HttpExchange exchange) throws IOException {
		String uri = exchange.getRequestURI().toString();

		String query = "";
		String content = "";
		String commit = "";
		String target;
		if (uri.indexOf("?") != -1) {
			target = uri.substring(0, uri.indexOf("?"));
			Hashtable ht = Utils.parseQueryString(uri.substring(uri
					.indexOf("?") + 1));
			// String uri = request.getRequestLine().getUri();
			String sArrayTemp_[] = (String[]) ht.get("query");
			query = (sArrayTemp_ != null) ? sArrayTemp_[0] : "";
			sArrayTemp_ = (String[]) ht.get("content");
			content = (sArrayTemp_ != null) ? sArrayTemp_[0] : "";
			sArrayTemp_ = ((String[]) ht.get("catelog"));
			commit = (sArrayTemp_ != null) ? sArrayTemp_[0] : "";
		} else {
			target = uri;
		}
		exchange.getResponseHeaders().set("Expires", "0");
		String toSend = null;
		int iCode = 200;
		if (target.endsWith("refresh")) {
			toSend = WebServer.refresh();
		} else if (target.endsWith("status")) {
			toSend = "setStatus('"
					+ (FrameAnt.getInstance("").getGuiAnt()
							.getConnectionAntPanel().getContainer().queryPanels
							.isEmpty() ? "load" : "ok") + "');";
		} else if (target.endsWith("get")) {
			toSend = WebServer.down(query);
		} else if (target.endsWith("open")) {
			WebServer.sendFile(exchange, query);
		} else if (target.endsWith("adddir")) {
			toSend = WebServer.adddir();
		} else if (target.endsWith("search") && (query != null)
				&& !query.equals("")) {
			toSend = WebServer.search(content, query, commit);
		} else if (target.endsWith("chat")) {
			toSend = WebServer.chat(query);
		} else {
			// not found
			toSend = "";
			iCode = 404;
		}
		if (toSend != null)
			WebServer.sendString(exchange, toSend, iCode);
	}

}
